<?php
/**
 * @name /lib/private/DonatedItem.php
 * @author Kimberly Berger <knb4850@esu.edu>
 * @author Michael Foss <michael@mikefoss.com>
 * @version 2011.03.30
 *
 * A DonatedItem class to manage DonatedItems
 *
 */

ReqLib('/lib/private/Item.php');
ReqLib('/lib/private/Donation.php');
/**
 * DonatedItem class.
 *
 */
class DonatedItem {
  /**
   * Donated item identification.
   *
   * @var integer
   */
  var $DonatedItemId;
  /**
   * The id of the donation to which this donated item belongs.
   *
   * @var integer
   */
  var $DonationId;
  /**
   * The item that was donated.
   *
   * @var Item
   */
  var $Item;
  /**
   * The quantity the user pledged to send.
   *
   * @var integer
   */
  var $QuantityPledged;
  /**
   * The quantity actually received.
   *
   * @var integer
   */
  var $QuantityReceived;
  /**
   * The last date that a package had arrived.
   *
   * @var string
   */
  var $LastDateReceived;
  /**
   * Donated item notes.
   *
   * @var string
   */
  var $Notes;

  /* Methods:

	"GET":
	DonatedItem[] GetDonatedItems(int offset, int maxResults)
	bool Exists(int donatedItemId)
	string ToString()

	"SCUD":
	bool Load(int donatedItemId)
	bool Create($DonationId, $ItemId)
	bool Save()
	static bool Delete(int donatedItemId)

	Custom:
	GetDonatedItemIdsByUserId(userId)
	GetDonatedItemIdsByItemId(itemId)
	GetDonatedItemIdsByUserIdAndItemId(userId, itemId)
    GetDonatedItemsByDonationId(donationId)
	*/


  /**
  *
  * Constructor.
  *
  */
  function DonatedItem(){
  	$this->DonatedItemId = 0;
    $this->DonationId = 0;
    $this->QuantityPledged = 0;
    $this->QuantityReceived = 0;
    $this->LastDateReceived = 0;
    $this->Notes = '';
    $this->Item = new Item();
  }

    /**
   * Generates a list of DonatedItems
   *
   * @param optional integer offset
   * @param optional integer maxResults
   * @return aray of DonatedItem Objects
   */
	function GetDonatedItems($offset = 0, $maxResults = 0){
		$objects = array();
		$db = new DB();
		// Initial query
		$query = "SELECT DonatedItemId FROM donateditems ORDER BY DonatedItemId";
		// Look for max results and offsets
		if ($maxResults && $maxResults * 1 == $maxResults) {
      $query .= " LIMIT $maxResults";
      if ($offset && $offset * 1 == $offset)
        $query .= " OFFSET $offset";
		}
		elseif ($offset && $offset * 1 == $offset)
      $query .= " LIMIT 99999999 OFFSET $offset";
		// Get the ids
		$ids = $db->QueryCol($query);
		// If we have ids, load the objects
		if (is_array($ids))
      foreach ($ids as $id) {
        $objects[count($objects)] = new DonatedItem();
        $objects[count($objects) - 1]->Load($id);
      }
		return $objects;
	}

  /**
   * Determines if a donateditem exists or not.
   *
   * @param integer
   * @return boolean
   */
  function Exists($donatedItemId){
    $db = new DB();
    return ($db->QueryVal("SELECT di.DonatedItemId FROM donateditems di WHERE di.DonatedItemId='" . addslashes($donatedItemId) . "' LIMIT 1;") > 0);
  }

  /**
  * Lists the attributes about a donated item.
  *
  * @param string (optional)
  * @return string
  */
  function ToString($del = '<br />') {
    $str = "";
	  $str .= 'DonatedItemId = ' . $this->DonatedItemId . $del;
	  $str .= 'DonationId = ' . $this->DonationId . $del;
	  $str .= 'Item = ' . $this->Item->ToString("\r\n");
	  $str .= 'QuantityPledged = ' . $this->QuantityPledged . $del;
	  $str .= 'QuantityReceived = ' . $this->QuantityReceived . $del;
	  $str .= 'DateReceived = ' . $this->DateReceived . $del;
    $str .= 'Notes = ' .$this->Notes . $del . $del;
	  return $str;
  }


  /**
   * Loads the DonatedItem information;
   * returns true on success, false on failure.
   *
   * @param integer
   * @return boolean
   */
  function Load($donatedItemId){
    if(!DonatedItem::Exists($donatedItemId)) // you can't load an item that doesn't exist
      return false;
    $db = new DB();
    $data = $db->QueryRow("
      SELECT
        DonationId,
        ItemId,
        QuantityPledged,
        QuantityReceived,
        UNIX_TIMESTAMP(LastDateReceived) AS LastDateReceived,
        Notes
      FROM
        donateditems
      WHERE
        DonatedItemId='" . addslashes($donatedItemId) . "';"
    );
    $this->Item = new Item();
    if (!$this->Item->Load($data["ItemId"])) //load the related item object
		return false;
    $this->DonationId = $data["DonationId"];
    $this->DonatedItemId = $donatedItemId;
    $this->LastDateReceived = $data["LastDateReceived"];
    $this->Notes = $data["Notes"];
    $this->QuantityPledged = $data["QuantityPledged"];
    $this->QuantityReceived = $data["QuantityReceived"];
    return true;
  }

  /**
   * Creates a donated item; requires DonationId to be set & Item to be loaded
   * returns true on success, false on failure.
   *
   * @param int
   * @param int
   * @return boolean
   */
  function Create($donationId, $itemId) {
    // only create a donation if the donation exists
    if (!Donation::Exists($donationId))
    // If the item doesn't exist, but it's not verified, create the item
    if (!$itemId && !$this->Item->IsVerified())
      $this->Item->Create($this->Item->Name);
    $db = new DB();
    $sql = "
      INSERT INTO donateditems (DonationId, ItemId) VALUES
      ('" . addslashes($donationId) ."', '" . addslashes($itemId) . "');"; //
    $db->Query($sql); // inserts the donated item
    $sql = "SELECT LAST_INSERT_ID();"; //selects the donateditemid
    $this->DonatedItemId = $db->QueryVal($sql);
    $this->DonationId = $donationId;
    $this->ItemId = $itemId;
    //tries to save the donated item
    if (!$this->Save()) {
      DonatedItem::Delete($this->DonatedItemId);
      $this->DonatedItemId = 0;
      $this->DonationId = 0;
      $this->ItemId = 0;
      return false;
    }
		return true;
  }

  /**
  * Saves a donated item;
  * returns true on success, false on failure.
  *
  * @return boolean
  */
  function Save(){
    // don't try to save an item if the donateditem or item doesn't exist
    if (!DonatedItem::Exists($this->DonatedItemId) || !Item::Exists($this->Item->ItemId) && $this->Item->ItemId > 0)
      return false;
    // If the item doesn't exist, but it's not verified, create the item
    if (!$this->Item->ItemId && !$this->Item->IsVerified())
      $this->Item->Create($this->Item->Name);
    $db = new DB();
    // Change quantity stored if necessary
    $oldQuantityReceived = $db->QueryVal("SELECT di.QuantityReceived FROM donateditems i WHERE di.DonatedItemId='" . addslashes($this->DonatedItemId) . "' LIMIT 1;");
    if ($oldQuantityReceived != $this->QuantityReceived)
      $db->Query("
        UPDATE items
        SET QuantityStored=QuantityStored+('" . addslashes($this->QuantityReceived - $oldQuantityReceived) . "')
        WHERE ItemId='" . addslashes($this->Item->ItemId) . "' LIMIT 1;
      ");
    // Make the update
    $data = $db->QueryRow("
      UPDATE donateditems SET
      ItemId='" . addslashes($this->Item->ItemId) . "',
      QuantityPledged='" . addslashes($this->QuantityPledged) . "',
      QuantityReceived='" . addslashes($this->QuantityReceived) . "',
      LastDateReceived='" . date('Y-m-d', $this->LastDateReceived). "',
      Notes='" . addslashes($this->Notes) . "'
      WHERE DonatedItemId='" . addslashes($this->DonatedItemId) . "';"
    );
    return true;
  }

  /**
   * Deletes a donated item;
   * returns true on success, false on failure.
   *
   * @static
   * @param integer
   * @return boolean
   */
  function Delete($donatedItemId) {
    if (!DonatedItem::Exists($donatedItemId)) //only try to delete a donateditem if the item exists
      return false;
    $db = new DB();
    $donatedItem = new DonatedItem();
    // Delete the item if it's not verified
    $donatedItem->Load($donatedItemId);
    if (!$donatedItem->Item->IsVerified())
      $itemId = $donatedItem->Item->ItemId;
    // delete the donated item
    $db->Query("DELETE FROM donateditems WHERE DonatedItemId='" . addslashes($donatedItemId) . "';");
    // Delete the item if we were actually able to grab the id - kinda' cheesy, but it works
    Item::Delete($itemId);
    return true;
  }

  /**
   * Gets an array of donated item ids by using the user id.
   *
   * @static
   * @param integer
   * @return integer[]
   */
  function GetDonatedItemIdsByUserId($userId) {
    $db = new DB();
    $donatedItemIds = $db->QueryCol("
      SELECT di.DonatedItemId
      FROM donateditems di
      INNER JOIN donations d
      ON di.DonationId=d.DonationId
      WHERE d.UserId='" . addslashes($userId) . "'
      ORDER BY di.DonationId;
    ");

    if (!$donatedItemIds)
      $donatedItemIds = array(); // make sure the donatedItemIds is an array
    return $donatedItemIds;
  }
  /**
  * STATIC METHOD
  * Gets an array of donated item ids by using the item id.
  *
  * @param integer
  * @return integer[]
  */
  function GetDonatedItemIdsByItemId($itemId){
    $db = new DB();
    $donatedItemIds = $db->QueryCol("
      SELECT di.DonatedItemId
      FROM donateditems di
      WHERE di.ItemId='" . addslashes($itemId) . "'
      ORDER BY di.DonationId;
    ");
    if (!$donatedItemIds)
      $donatedItemIds = array();// make sure donateItemIds is an array
    return $donatedItemIds;
  }

  /**
  * STATIC METHOD
  * Gets an array of donated item ids by using the user id and item id.
  *
  *  @param integer
  *  @param integer
  *  @return integer[]
  */
  function GetDonatedItemIdsByUserIdAndItemId($userId, $itemId){
    $db = new DB();
    $donatedItemIds = $db->QueryCol("
      SELECT di.DonatedItemId
      FROM donateditems di
      INNER JOIN donations d
      ON di.DonationId=d.DonationId
      WHERE d.UserId='" . addslashes($userId) . "'
      AND di.ItemId='" . addslashes($itemId) . "'
      ORDER BY di.DonationId;
    ");
    if (!$donatedItemIds)
      $donatedItemIds = array(); // make sure donateItemIds is an array
    return $donatedItemIds;
  }

  /**
   * Given a donation id, gets all DonatedItems
   * belonging to that Donation.
   *
   * @static
   * @param int
   * @return DonatedItem[]
   */
  function GetDonatedItemsByDonationId($donationId) {
    $db = new DB();
    $ids = $db->QueryCol("SELECT di.DonatedItemId FROM donateditems di WHERE di.DonationId='" . addslashes($donationId) . "';");
    $donations = array(); //make donations an array
    if ($ids) // if there is something in ids load each of the donateditems
      foreach ($ids as $id) {
        $di = new DonatedItem();
        $di->Load($id);
        $donations[] = $di;
      }
    return $donations;
  }
}
